package com.sias.springboot;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * @author 吴文杰
 * @version 1.0
 * @since 2023/5/31 14:43
 */
public class TestBeanFactory {
  public static void main(String[] args) {
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
    beanFactory.registerBeanDefinition("config",beanDefinition);

    /**
     * BeanFactory后处理器
     * org.springframework.context.annotation.internalConfigurationAnnotationProcessor
     * org.springframework.context.annotation.internalAutowiredAnnotationProcessor
     *
     * bean后处理
     * org.springframework.context.annotation.internalCommonAnnotationProcessor
     * org.springframework.context.event.internalEventListenerProcessor
     * org.springframework.context.event.internalEventListenerFactory
     */

    // 给BeanFactory添加一些常用的后处理器
    AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

    // BeanFactory后处理器主要功能  补充了一些bean定义
    beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach(beanFactoryPostProcessor->{
      beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
    });

    // Bean 后处理器  针对Bean的生命周期的各个阶段提供扩展  例如@Autowired @Resource
    beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream()
            .sorted(beanFactory.getDependencyComparator())
            .forEach(beanPostProcessor -> {
        System.out.println(">>>"+beanPostProcessor);
        beanFactory.addBeanPostProcessor(beanPostProcessor);
    });

    for (String name : beanFactory.getBeanDefinitionNames()) {
      System.out.println(name);
    }

    System.out.println("==============================================");
    beanFactory.preInstantiateSingletons(); // 准备好所有单例

    System.out.println(beanFactory.getBean(Bean1.class).getBean2());
    System.out.println(beanFactory.getBean(Bean1.class).getInter());

    /**
     * beanFactory: 不会做的事
     *    1. 不会主动调用BeanFactory 后处理器
     *    2. 不会主动添加Bean 后处理器
     *    3. 不会主动初始化单例
     *    4. 不会解析beanFactory  还不会解析 ${} 和 #{}
     * bean 后处理器会有排序的逻辑
     */
  }

  @Configuration
  static class Config {


    @Bean
    public Bean1 bean1() {
      return new Bean1();
    }

    @Bean
    public Bean2 bean2() {
      return new Bean2();
    }

    @Bean
    public Bean3 bean3() {
      return new Bean3();
    }

    @Bean
    public Bean4 bean4() {
      return new Bean4();
    }
  }

  interface Inter{

  }

  static class Bean3 implements Inter{

  }
  static class Bean4 implements Inter{

  }
  static class Bean1 {
    private static final Logger Log = LoggerFactory.getLogger(Bean1.class);

    public Bean1() {
      Log.debug("构造 Bean1");
    }

    @Autowired
    Bean2 bean2;

    public Bean2 getBean2() {
      return bean2;
    }

    @Resource(name = "bean4")
    @Autowired
    private Inter bean3;

    public Inter getInter() {
      return bean3;
    }
  }

  static class Bean2 {
    private static final Logger Log = LoggerFactory.getLogger(Bean2.class);

    public Bean2() {
      Log.debug("构造 bean2");
    }
  }

}
